package com.jeasonzhao.commons.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class WebColor implements java.io.Serializable
{
    private static final long serialVersionUID = 1L;
    private int m_nRed = -1;
    private int m_nGreen = -1;
    private int m_nBlue = -1;
    public static final WebColor Empty = new WebColor( -1, -1, -1);
    public WebColor(int redValue,int greenValue,int blueValue)
    {
        initilizeColor(redValue,greenValue,blueValue);
    }

    public WebColor(String strColor)
    {
        if(null == strColor || strColor.trim().length() < 1)
        {
            return;
        }
        strColor = strColor.trim();
        WebColor clr = WebColor.findByName(strColor);
        if(null != clr)
        {
            this.m_nBlue = clr.m_nBlue;
            this.m_nGreen = clr.m_nGreen;
            this.m_nRed = clr.m_nRed;
            return;
        }
        else
        {
            if(strColor.startsWith("#"))
            {
                strColor = strColor.substring(1);
            }
            if(strColor.toLowerCase().startsWith("0x"))
            {
                strColor = strColor.substring(2);
            }
            int r = strColor.length() >= 2 ? Integer.parseInt(strColor.substring(0,2),16) : 0;
            int g = strColor.length() >= 4 ? Integer.parseInt(strColor.substring(2,4),16) : 0;
            int b = strColor.length() >= 6 ? Integer.parseInt(strColor.substring(4,6),16) : 0;
            initilizeColor(r,g,b);
        }
    }

    public String toString()
    {
        return this.getColorName();
    }

    public static boolean isEmpty(WebColor clr)
    {
        return null == clr || clr.m_nBlue * clr.m_nGreen * clr.m_nRed < 0;
    }

    public boolean isEmpty()
    {
        return m_nBlue * m_nGreen * m_nRed < 0;
    }

    public WebColor alpha(double n)
    {
        n = Math.abs(n);
        return new WebColor((int) (m_nRed * n) % 255,(int) (m_nGreen * n) % 255,(int) (m_nBlue * n) % 255);
    }

    public WebColor alpha(WebColor clr,double n)
    {
        if(null == clr)
        {
            return alpha(n);
        }
        else
        {
            n = Math.abs(n);
            return new WebColor((int) (m_nRed * n) % 255 + (int) (clr.m_nRed * n) % 255,
                                (int) (m_nGreen * n) % 255 + (int) (clr.m_nGreen * n) % 255,
                                (int) (m_nBlue * n) % 255 + (int) (clr.m_nBlue * n) % 255);
        }
    }

    public WebColor reverse()
    {
        return new WebColor(128 - m_nRed,128 - m_nGreen,128 - m_nBlue);
    }

    private void initilizeColor(int redValue,int greenValue,int blueValue)
    {
        m_nRed = Math.abs(redValue)%255;
        m_nGreen = Math.abs(greenValue)%255;
        m_nBlue = Math.abs(blueValue)%255;
    }
    public static final java.util.ArrayList<String> knownColorNames()
    {
        initMap();
       return m_originalNames;
    }
    ///////////////////////////////////////////////////////////////////////////
    private static volatile java.util.Hashtable<String,WebColor> m_cachedMapOfString = null;
    private static volatile java.util.ArrayList<String> m_originalNames=null;
    private static final WebColor findByName(String strName)
    {
        initMap();
        return null == m_cachedMapOfString || null == strName
            ? null
            : m_cachedMapOfString.get(strName.toUpperCase().trim());
    }

    public String getColorName()
    {
        initMap();
        if(null != m_cachedMapOfString)
        {
            for(java.util.Map.Entry<String,WebColor> c : m_cachedMapOfString.entrySet())
            {
                if(c.getValue().m_nBlue == this.m_nBlue
                   && c.getValue().m_nGreen == this.m_nGreen
                   && c.getValue().m_nRed == this.m_nRed)
                {
                    if(null!=m_originalNames)
                    {
                        for(String s: m_originalNames)
                        {
                            if(s.equalsIgnoreCase(c.getKey()))
                            {
                                return s;
                            }
                        }
                    }
                    return c.getKey();
                }
            }
        }
        return getHexString();
    }

    public String getHexString()
    {
        String name = "#";
        String str = Integer.toHexString(this.m_nRed);
        name += str.length() < 2 ? "0" + str : str;
        str = Integer.toHexString(this.m_nGreen);
        name += str.length() < 2 ? "0" + str : str;
        str = Integer.toHexString(this.m_nBlue);
        name += str.length() < 2 ? "0" + str : str;
        return name.toUpperCase();
    }

    private static void initMap()
    {
        if(null == m_cachedMapOfString)
        {
            synchronized(WebColor.class)
            {
                m_cachedMapOfString = new java.util.Hashtable<String,WebColor>();
                m_originalNames=new java.util.ArrayList<String>();
                try
                {
                    Field[] fields = WebColor.class.getDeclaredFields();
                    for(int n = 0;n < fields.length;n++)
                    {
                        Field f = fields[n];
                        f.setAccessible(true);
                        if(Modifier.isStatic(f.getModifiers())
                           && f.getType().equals(WebColor.class))
                        {
                            WebColor clr = (WebColor) f.get(null);
                            m_cachedMapOfString.put(f.getName().toUpperCase(),clr);
                            m_originalNames.add(f.getName());
                        }
                    }
                }
                catch(Exception ex)
                {
                    ex.printStackTrace();
                }

            } //sync block.
        } //check map
    }

    ///////////////////////////////////////////////////////////////////
    public static final WebColor AliceBlue = new WebColor(240,248,255);
    public static final WebColor AntiqueWhite = new WebColor(250,235,215);
    public static final WebColor Aqua = new WebColor(0,255,255);
    public static final WebColor Aquamarine = new WebColor(127,255,212);
    public static final WebColor Azure = new WebColor(240,255,255);
    public static final WebColor Beige = new WebColor(245,245,220);
    public static final WebColor Bisque = new WebColor(255,228,196);
    public static final WebColor Black = new WebColor(0,0,0);
    public static final WebColor BlanchedAlmond = new WebColor(255,235,205);
    public static final WebColor Blue = new WebColor(0,0,255);
    public static final WebColor BlueViolet = new WebColor(138,43,226);
    public static final WebColor Brown = new WebColor(165,42,42);
    public static final WebColor BurlyWood = new WebColor(222,184,135);
    public static final WebColor CadetBlue = new WebColor(95,158,160);
    public static final WebColor Chartreuse = new WebColor(127,255,0);
    public static final WebColor Chocolate = new WebColor(210,105,30);
    public static final WebColor Coral = new WebColor(255,127,80);
    public static final WebColor CornflowerBlue = new WebColor(100,149,237);
    public static final WebColor Cornsilk = new WebColor(255,248,220);
    public static final WebColor Crimson = new WebColor(220,20,60);
    public static final WebColor Cyan = new WebColor(0,255,255);
    public static final WebColor DarkBlue = new WebColor(0,0,139);
    public static final WebColor DarkCyan = new WebColor(0,139,139);
    public static final WebColor DarkGoldenrod = new WebColor(184,134,11);
    public static final WebColor DarkGray = new WebColor(169,169,169);
    public static final WebColor DarkGreen = new WebColor(0,100,0);
    public static final WebColor DarkKhaki = new WebColor(189,183,107);
    public static final WebColor DarkMagenta = new WebColor(139,0,139);
    public static final WebColor DarkOliveGreen = new WebColor(85,107,47);
    public static final WebColor DarkOrange = new WebColor(255,140,0);
    public static final WebColor DarkOrchid = new WebColor(153,50,204);
    public static final WebColor DarkRed = new WebColor(139,0,0);
    public static final WebColor DarkSalmon = new WebColor(233,150,122);
    public static final WebColor DarkSeaGreen = new WebColor(143,188,139);
    public static final WebColor DarkSlateBlue = new WebColor(72,61,139);
    public static final WebColor DarkSlateGray = new WebColor(47,79,79);
    public static final WebColor DarkTurquoise = new WebColor(0,206,209);
    public static final WebColor DarkViolet = new WebColor(148,0,211);
    public static final WebColor DeepPink = new WebColor(255,20,147);
    public static final WebColor DeepSkyBlue = new WebColor(0,191,255);
    public static final WebColor DimGray = new WebColor(105,105,105);
    public static final WebColor DodgerBlue = new WebColor(30,144,255);
    public static final WebColor Firebrick = new WebColor(178,34,34);
    public static final WebColor FloralWhite = new WebColor(255,250,240);
    public static final WebColor ForestGreen = new WebColor(34,139,34);
    public static final WebColor Fuchsia = new WebColor(255,0,255);
    public static final WebColor Gainsboro = new WebColor(220,220,220);
    public static final WebColor GhostWhite = new WebColor(248,248,255);
    public static final WebColor Gold = new WebColor(255,215,0);
    public static final WebColor Goldenrod = new WebColor(218,165,32);
    public static final WebColor Gray = new WebColor(128,128,128);
    public static final WebColor Green = new WebColor(0,128,0);
    public static final WebColor GreenYellow = new WebColor(173,255,47);
    public static final WebColor Honeydew = new WebColor(240,255,240);
    public static final WebColor HotPink = new WebColor(255,105,180);
    public static final WebColor IndianRed = new WebColor(205,92,92);
    public static final WebColor Indigo = new WebColor(75,0,130);
    public static final WebColor Ivory = new WebColor(255,255,240);
    public static final WebColor Khaki = new WebColor(240,230,140);
    public static final WebColor Lavender = new WebColor(230,230,250);
    public static final WebColor LavenderBlush = new WebColor(255,240,245);
    public static final WebColor LawnGreen = new WebColor(124,252,0);
    public static final WebColor LemonChiffon = new WebColor(255,250,205);
    public static final WebColor LightBlue = new WebColor(173,216,230);
    public static final WebColor LightCoral = new WebColor(240,128,128);
    public static final WebColor LightCyan = new WebColor(224,255,255);
    public static final WebColor LightGoldenrodYellow = new WebColor(250,250,210);
    public static final WebColor LightGray = new WebColor(211,211,211);
    public static final WebColor LightGreen = new WebColor(144,238,144);
    public static final WebColor LightPink = new WebColor(255,182,193);
    public static final WebColor LightSalmon = new WebColor(255,160,122);
    public static final WebColor LightSeaGreen = new WebColor(32,178,170);
    public static final WebColor LightSkyBlue = new WebColor(135,206,250);
    public static final WebColor LightSlateGray = new WebColor(119,136,153);
    public static final WebColor LightSteelBlue = new WebColor(176,196,222);
    public static final WebColor LightYellow = new WebColor(255,255,224);
    public static final WebColor Lime = new WebColor(0,255,0);
    public static final WebColor LimeGreen = new WebColor(50,205,50);
    public static final WebColor Linen = new WebColor(250,240,230);
    public static final WebColor Magenta = new WebColor(255,0,255);
    public static final WebColor Maroon = new WebColor(128,0,0);
    public static final WebColor MediumAquamarine = new WebColor(102,205,170);
    public static final WebColor MediumBlue = new WebColor(0,0,205);
    public static final WebColor MediumOrchid = new WebColor(186,85,211);
    public static final WebColor MediumPurple = new WebColor(147,112,219);
    public static final WebColor MediumSeaGreen = new WebColor(60,179,113);
    public static final WebColor MediumSlateBlue = new WebColor(123,104,238);
    public static final WebColor MediumSpringGreen = new WebColor(0,250,154);
    public static final WebColor MediumTurquoise = new WebColor(72,209,204);
    public static final WebColor MediumVioletRed = new WebColor(199,21,133);
    public static final WebColor MidnightBlue = new WebColor(25,25,112);
    public static final WebColor MintCream = new WebColor(245,255,250);
    public static final WebColor MistyRose = new WebColor(255,228,225);
    public static final WebColor Moccasin = new WebColor(255,228,181);
    public static final WebColor NavajoWhite = new WebColor(255,222,173);
    public static final WebColor Navy = new WebColor(0,0,128);
    public static final WebColor OldLace = new WebColor(253,245,230);
    public static final WebColor Olive = new WebColor(128,128,0);
    public static final WebColor OliveDrab = new WebColor(107,142,35);
    public static final WebColor Orange = new WebColor(255,165,0);
    public static final WebColor OrangeRed = new WebColor(255,69,0);
    public static final WebColor Orchid = new WebColor(218,112,214);
    public static final WebColor PaleGoldenrod = new WebColor(238,232,170);
    public static final WebColor PaleGreen = new WebColor(152,251,152);
    public static final WebColor PaleTurquoise = new WebColor(175,238,238);
    public static final WebColor PaleVioletRed = new WebColor(219,112,147);
    public static final WebColor PapayaWhip = new WebColor(255,239,213);
    public static final WebColor PeachPuff = new WebColor(255,218,185);
    public static final WebColor Peru = new WebColor(205,133,63);
    public static final WebColor Pink = new WebColor(255,192,203);
    public static final WebColor Plum = new WebColor(221,160,221);
    public static final WebColor PowderBlue = new WebColor(176,224,230);
    public static final WebColor Purple = new WebColor(128,0,128);
    public static final WebColor Red = new WebColor(255,0,0);
    public static final WebColor RosyBrown = new WebColor(188,143,143);
    public static final WebColor RoyalBlue = new WebColor(65,105,225);
    public static final WebColor SaddleBrown = new WebColor(139,69,19);
    public static final WebColor Salmon = new WebColor(250,128,114);
    public static final WebColor SandyBrown = new WebColor(244,164,96);
    public static final WebColor SeaGreen = new WebColor(46,139,87);
    public static final WebColor SeaShell = new WebColor(255,245,238);
    public static final WebColor Sienna = new WebColor(160,82,45);
    public static final WebColor Silver = new WebColor(192,192,192);
    public static final WebColor SkyBlue = new WebColor(135,206,235);
    public static final WebColor SlateBlue = new WebColor(106,90,205);
    public static final WebColor SlateGray = new WebColor(112,128,144);
    public static final WebColor Snow = new WebColor(255,250,250);
    public static final WebColor SpringGreen = new WebColor(0,255,127);
    public static final WebColor SteelBlue = new WebColor(70,130,180);
    public static final WebColor Tan = new WebColor(210,180,140);
    public static final WebColor Teal = new WebColor(0,128,128);
    public static final WebColor Thistle = new WebColor(216,191,216);
    public static final WebColor Tomato = new WebColor(255,99,71);
    public static final WebColor Transparent = new WebColor(255,255,255);
    public static final WebColor Turquoise = new WebColor(64,224,208);
    public static final WebColor Violet = new WebColor(238,130,238);
    public static final WebColor Wheat = new WebColor(245,222,179);
    public static final WebColor White = new WebColor(255,255,255);
    public static final WebColor WhiteSmoke = new WebColor(245,245,245);
    public static final WebColor Yellow = new WebColor(255,255,0);
    public static final WebColor YellowGreen = new WebColor(154,205,50);

    public static void main(String[] argvs)
    {
        WebColor c=new WebColor(255,0,0);
        System.out.println(c.getColorName()+"="+c.getHexString());
    }
} //end of class Color
